package com.cchip.cloud.api;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;

import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.params.HttpClientParams;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;

import android.util.Log;
import com.cchip.cloud.system.Config;

public class MeetingApi {

	private static MeetingApi mInstance = null;

	private final String REGISTER_URL = "/k2voice/register.php";
	private final String LOGIN_URL = "/k2voice/login.php";
	private final String KNOCK_ROOM_URL = "/k2voice/find_room_pwd.php";
	private final String ENTER_ROOM_URL = "/k2voice/room_match_pwd.php";
	private final String SET_USER_PWD_URL = "/k2voice/change_password.php";
	private final String SET_ROOM_PWD_URL = "/k2voice/change_room_pwd.php";

	private DefaultHttpClient mClient;
	private HttpParams mReqParams = null;

	public static MeetingApi getInstance() {
		if (mInstance == null)
			mInstance = new MeetingApi();
		return mInstance;
	}

	private MeetingApi() {
		if (null == mClient) {
			HttpParams params = new BasicHttpParams();

			HttpConnectionParams.setTcpNoDelay(params, true);
			HttpClientParams.setRedirecting(params, true);
			HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
			HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
			HttpProtocolParams.setUseExpectContinue(params, false);
			HttpConnectionParams.setSocketBufferSize(params, 8192);

			SchemeRegistry supportedSchemes = new SchemeRegistry();
			supportedSchemes.register(new Scheme("http", PlainSocketFactory
					.getSocketFactory(), 80));
			supportedSchemes.register(new Scheme("Https", SSLSocketFactory
					.getSocketFactory(), 443));
			ClientConnectionManager ccm = new ThreadSafeClientConnManager(
					params, supportedSchemes);
			mClient = new DefaultHttpClient(ccm, params);

			mReqParams = new BasicHttpParams();
			HttpConnectionParams.setSoTimeout(mReqParams, 10000);
			HttpConnectionParams.setConnectionTimeout(mReqParams, 10000);
		}
	}

	private MeetingReturned parseResponse(InputStream is)
			throws IllegalStateException, IOException {
		MeetingReturned returned = null;
		BufferedReader reader = new BufferedReader(new InputStreamReader(is,
				HTTP.UTF_8));

		String line;
		returned = new MeetingReturned();
		while ((line = reader.readLine()) != null) {
			String[] array = line.split("=");
			String k = new String(array[0]);
			String v = new String(array[1]);
			if (k.equals("oper_result")) {
				returned.operCode = Integer.parseInt(v);
			} else if (k.equals("roomid")) {
				returned.roomId = v;
			} else if (k.equals("username")) {
				returned.roomName = v;
			} else if (k.equals("is_pwd")) {
				returned.needPassword = v.equals("1");
			}
		}

		return returned;
	}

	private MeetingReturned post(HttpPost postReq) {
		HttpHost host = new HttpHost(Config.getHttpHost(), 80);

		HttpResponse response = null;
		InputStream is = null;
		MeetingReturned returned = null;

		try {
			response = mClient.execute(host, postReq);
			if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
				is = response.getEntity().getContent();
				if (is != null) {
					returned = parseResponse(is);
					is.close();
				}
			}

			response.getEntity().consumeContent();
		} catch (ClientProtocolException e) {
			Log.e("MeetingApi", "Post Failed", e);
		} catch (IOException e) {
			Log.e("MeetingApi", "Post Failed", e);
		}
		return returned;
	}

	public MeetingReturned register(String username, String password,
			String email) {
		MeetingReturned returned = null;
		HttpPost postReq = new HttpPost(REGISTER_URL);
		postReq.setParams(mReqParams);

		ArrayList<NameValuePair> paramList = new ArrayList<NameValuePair>();
		NameValuePair nvp1 = new BasicNameValuePair("username", username);
		NameValuePair nvp2 = new BasicNameValuePair("pwd", password);
		NameValuePair nvp3 = new BasicNameValuePair("email", email);
		paramList.add(nvp1);
		paramList.add(nvp2);
		paramList.add(nvp3);

		try {
			postReq.setEntity(new UrlEncodedFormEntity(paramList, HTTP.UTF_8));
			returned = post(postReq);
		} catch (UnsupportedEncodingException e) {
			Log.i("MeetingApi", "register failed", e);
		}

		return returned;
	}

	public MeetingReturned login(String username, String password) {
		MeetingReturned returned = null;
		HttpPost postReq = new HttpPost(LOGIN_URL);
		postReq.setParams(mReqParams);

		ArrayList<NameValuePair> paramList = new ArrayList<NameValuePair>();
		NameValuePair nvp1 = new BasicNameValuePair("username", username);
		NameValuePair nvp2 = new BasicNameValuePair("pwd", password);
		paramList.add(nvp1);
		paramList.add(nvp2);

		try {
			postReq.setEntity(new UrlEncodedFormEntity(paramList, HTTP.UTF_8));
			returned = post(postReq);
		} catch (UnsupportedEncodingException e) {
			Log.i("MeetingApi", "login failed", e);
		}

		return returned;
	}

	public MeetingReturned knockRoom(String roomid) {
		MeetingReturned returned = null;
		HttpPost postReq = new HttpPost(KNOCK_ROOM_URL);
		postReq.setParams(mReqParams);

		ArrayList<NameValuePair> paramList = new ArrayList<NameValuePair>();
		NameValuePair nvp1 = new BasicNameValuePair("roomid", roomid);
		paramList.add(nvp1);

		try {
			postReq.setEntity(new UrlEncodedFormEntity(paramList, HTTP.UTF_8));
			returned = post(postReq);
		} catch (UnsupportedEncodingException e) {
			Log.i("MeetingApi", "knock room", e);
		}

		return returned;
	}

	public MeetingReturned enterRoom(String roomid, String roompassword) {
		MeetingReturned returned = null;
		HttpPost postReq = new HttpPost(ENTER_ROOM_URL);
		postReq.setParams(mReqParams);

		ArrayList<NameValuePair> paramList = new ArrayList<NameValuePair>();
		NameValuePair nvp1 = new BasicNameValuePair("roomid", roomid);
		paramList.add(nvp1);
		NameValuePair nvp2 = new BasicNameValuePair("pwd", roompassword);
		paramList.add(nvp2);

		try {
			postReq.setEntity(new UrlEncodedFormEntity(paramList, HTTP.UTF_8));
			returned = post(postReq);
		} catch (UnsupportedEncodingException e) {
			Log.i("MeetingApi", "enter room failed", e);
		}

		return returned;
	}

	public MeetingReturned setUserPassword(String username, String oldpassword,
			String newpassword) {
		MeetingReturned returned = null;
		HttpPost postReq = new HttpPost(SET_USER_PWD_URL);
		postReq.setParams(mReqParams);

		ArrayList<NameValuePair> paramList = new ArrayList<NameValuePair>();
		NameValuePair nvp1 = new BasicNameValuePair("username", username);
		NameValuePair nvp2 = new BasicNameValuePair("oldpwd", oldpassword);
		NameValuePair nvp3 = new BasicNameValuePair("newpwd", newpassword);
		paramList.add(nvp1);
		paramList.add(nvp2);
		paramList.add(nvp3);

		try {
			postReq.setEntity(new UrlEncodedFormEntity(paramList, HTTP.UTF_8));
			returned = post(postReq);
		} catch (UnsupportedEncodingException e) {
			Log.i("MeetingApi", "Set user password failed", e);
		}

		return returned;
	}

	public MeetingReturned setRoomPassword(String username, String password,
			String roompassword) {
		MeetingReturned returned = null;
		HttpPost postReq = new HttpPost(SET_ROOM_PWD_URL);
		postReq.setParams(mReqParams);

		ArrayList<NameValuePair> paramList = new ArrayList<NameValuePair>();
		NameValuePair nvp1 = new BasicNameValuePair("username", username);
		NameValuePair nvp2 = new BasicNameValuePair("pwd", password);
		NameValuePair nvp3 = new BasicNameValuePair("new_room_pwd",
				roompassword);
		paramList.add(nvp1);
		paramList.add(nvp2);
		paramList.add(nvp3);

		try {
			postReq.setEntity(new UrlEncodedFormEntity(paramList, HTTP.UTF_8));
			returned = post(postReq);
		} catch (UnsupportedEncodingException e) {
			Log.i("MeetingApi", "Set room password failed", e);
		}

		return returned;
	}

}
